const plugin = require('tailwindcss/plugin')


const hslColors = plugin(
  ({ matchUtilities, theme }) => {
    let i = 0;
    const values = {};

    do {
      let j = 0;
      do {
        values[`${i}-${j}`] = `${i}-${j}`;
        let k = 0;
        do {
          values[`${i}-${j}/${k}`] = `${i}-${j}/${k}`;
          k += 10;
        } while (k <= 100);
        j += 10;
      } while (j <= 100);
      i += 10;
    } while (i <= 100);

    const utilities = {};
    const colors = theme('hslColors');
    const cssAttrs = [
      'text',
      'bg',
      'border',
      'border-t',
      'border-r',
      'border-b',
      'border-l',
      'divide',
      'caret',
      'outline',
      'outline-solid',
      'outline-dotted',
      'placeholder',
      'shadow',
      'ring',
      'ring-offset',
      'decoration',
    ];
    cssAttrs.forEach((item) => {
      for (const [name, h] of Object.entries(colors)) {
        utilities[`${item}-${name}`] = (value) => {
          const [s, la] = value.split('-');

          const [l, a] = la.split('/');

          let varItem;

          if (item.startsWith('border')) {
            varItem = 'border';
          } else if (item.startsWith('outline')) {
            varItem = 'outline';
          } else {
            varItem = item;
          }

          let result = {};
          const opacity = a === undefined ? '1' : (a / 100).toString();
          const color = `hsl(${h}deg ${s}% ${l}% / var(--tw-${varItem}-opacity))`;
          const colorNoVar = `hsl(${h}deg ${s}% ${l}% / ${opacity})`;

          switch (item) {
            case 'text':
            case 'placeholder':
              result[`--tw-${varItem}-opacity`] = opacity;
              result.color = color;
              break;
            case 'bg':
              result[`--tw-${varItem}-opacity`] = opacity;
              result['background-color'] = color;
              break;
            case 'border':
              result[`--tw-${varItem}-opacity`] = opacity;
              result['border-color'] = color;
              break;
            case 'border-t':
              opacity !== '1' && (result[`--tw-${varItem}-opacity`] = opacity);
              result['border-top-color'] = opacity === '1' ? color : colorNoVar;
              break;
            case 'border-r':
              opacity !== '1' && (result[`--tw-${varItem}-opacity`] = opacity);
              result['border-right-color'] = opacity === '1' ? color : colorNoVar;
              break;
            case 'border-b':
              opacity !== '1' && (result[`--tw-${varItem}-opacity`] = opacity);
              result['border-bottom-color'] = opacity === '1' ? color : colorNoVar;
              break;
            case 'border-l':
              opacity !== '1' && (result[`--tw-${varItem}-opacity`] = opacity);
              result['border-left-color'] = opacity === '1' ? color : colorNoVar;
              break;
            case 'divide':
              result['& > :not([hidden]) ~ :not([hidden])'] = {
                [`--tw-${varItem}-opacity`]: opacity,
                'border-color': color
              }
              break;
            case 'caret':
              result[`--tw-${varItem}-opacity`] = opacity;
              result['caret-color'] = color;
              break;
            case 'outline':
            case 'outline-solid':
            case 'outline-dotted':
              result[`--tw-${varItem}-opacity`] = opacity;
              result['outline-color'] = color;
              break;
            case 'shadow':
              result['--tw-shadow-color'] = colorNoVar;
              result['--tw-shadow'] = 'var(--tw-shadow-colored)';
              break;
            case 'ring':
            case 'ring-offset':
              result[`--tw-${varItem}-opacity`] = opacity;
              result[`--tw-${name}-color`] = color;
              break;
            case 'decoration':
              result['-webkit-text-decoration-color'] = color;
              result['text-decoration-color'] = color;
              break;
            default:
              result = undefined;
              break;
          }
          return result;
        };
      }
    })

    matchUtilities(utilities, { values });
  },
  {
    theme: {
      hslColors: {
        primary: '216',
        success: '152',
        danger: '354',
        warning: '45',
        info: '190',
        secondary: '210'
      }
    },
    variants: {
      hslColors: ['responsive'],
    }
  }
);

module.exports = hslColors;
